import Dep from './Dep.js'
import dependArray from './dependArray.js'
import observe from './observe.js'
export default function (obj, key, val, customSetter, shallow) {
  const dep = new Dep() // 
  // 查找对象的目标属性
  const property = Object.getOwnPropertyDescriptor(obj, key)
  //当且仅当指定对象的属性描述可以被改变或者属性可被删除时
  // 如果false 属性无法改变了，没办法动态改变了
  if (property && property.configurable === false) {
    return
  }
  const getter = property && property.get
  const setter = property && property.set
  if ((!getter || setter) && arguments.length === 2) {
    // 防止不传val
    val = obj[key]
  }
  let childOb = !shallow && observe(val)
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      // 如果属性存在get 就拿到 
      const value = getter ? getter.call(obj) : val
      if (Dep.target) { // 如果有
        dep.depend() // 添加
        if (childOb) { // 如果有child child添加
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value) // 未来写
          }
        }
      }
      return value
    },
    set: function reactiveSetter(newVal) {
      // 拿到value
      const value = getter ? getter.call(obj) : val
      // 如果相同就return
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      // 如果没有set也return
      if (getter && !setter) return
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      childOb = !shallow && observe(newVal)
      dep.notify() // 通知
    }
  })

}